export function toHexString(num, digits = 6) {
	// 将数字转换为十六进制字符串，并去掉 '0x' 前缀
	let hexString = num.toString(16).toUpperCase();
	// 使用 padStart 补零，确保长度为3位
	return hexString.padStart(digits, "0");
}

export function decimalArrayToHexString(decimalArray) {
	if (!(decimalArray instanceof Uint8Array)) throw new Error("Invalid input: decimalArray must be a Uint8Array");
	let hexString = "";

	for (let i = 0; i < decimalArray.length; i++) {
		// 使用toString方法将十进制数字转换为十六进制字符串，并指定基数为16
		let hex = decimalArray[i].toString(16);

		// 如果十六进制字符串的长度不足2位，添加前导零
		if (hex.length < 2) {
			hex = "0" + hex;
		}

		// 将转换后的十六进制字符串追加到结果字符串中
		hexString += hex;
	}

	return hexString;
}

export function getUnixTimeAndZone() {
	const date = new Date();
	const timestamp = date.getTime();
	const zone = date.getTimezoneOffset();
	const hex = timestamp.toString(16).toUpperCase().padStart(16, "0");
	const hexArr = hex.match(/.{1,2}/g).reverse();
	const decimalArr = hexArr.map((hex) => parseInt(hex, 16));
	return {
		date,
		timestamp,
		zone: zone / 60,
		hex,
		hexArr,
		decimalArr,
	};
}

export function timestamp2Arr(ts) {
	const date = new Date(ts);
	if (date.toString() === "Invalid Date") throw new Error("Invalid Date");
	const timestamp = date.getTime();
	const zone = date.getTimezoneOffset();
	const hex = timestamp.toString(16).toUpperCase().padStart(16, "0");
	const hexArr = hex.match(/.{1,2}/g).reverse();
	const decimalArr = hexArr.map((hex) => parseInt(hex, 16));
	return {
		date,
		timestamp,
		zone: zone / 60,
		hex,
		hexArr,
		decimalArr,
	};
}

export function isValidZeroOrOne(value) {
	return value === 0 || value === 1;
}

/**
 * 移除数组末尾的零值对象
 * 该函数旨在处理一个对象数组，移除数组末尾所有价值为零的对象，直到遇到第一个非零值对象为止
 * @param {Array} arr - 一个包含对象的数组，其中对象具有一个value属性，表示数值
 * @returns {Array} - 移除末尾零值对象后的数组
 */
export const removeTrailingZeros = (arr) => {
	// 找到最后一个非零值对象的索引
	let lastNonZeroIndex = -1;
	for (let i = 0; i < arr.length; i++) {
		if (arr[i].value !== 0) {
			lastNonZeroIndex = i;
		}
	}

	// 如果没有找到非零值对象，返回原数组
	if (lastNonZeroIndex === -1) {
		return arr;
	}

	// 返回去掉最后一个非零值对象之后的所有零对象的数组
	return arr.slice(0, lastNonZeroIndex + 1);
};

// 等待
export async function waiting(t = 0) {
	return await new Promise(async (resolve, reject) => {
		const timer = setTimeout(() => {
			clearTimeout(timer);
			resolve(true);
		}, t);
	});
}

function deepCloneMap(originalMap) {
	const clonedMap = new Map();

	originalMap.forEach((value, key) => {
		// 递归深拷贝键和值
		clonedMap.set(deepClone(key), deepClone(value));
	});

	return clonedMap;
}

export function deepClone(obj) {
	if (obj instanceof Map) {
		return deepCloneMap(obj);
	}

	// 如果是 null 或者不是对象，直接返回
	if (obj === null || typeof obj !== "object") {
		return obj;
	}

	// 处理数组
	if (Array.isArray(obj)) {
		return obj.map((item) => deepClone(item));
	}

	// 处理对象
	const clonedObj = {};
	for (const key in obj) {
		if (obj.hasOwnProperty(key)) {
			clonedObj[key] = deepClone(obj[key]);
		}
	}

	return clonedObj;
}

/**
 * 获取用户步长
 * 公式为 stepLength = height * H
 * H为 男*0.413  女*0.415
 * @param {*} height 身高 cm
 * @param {*} gender 性别
 * @returns stepLength cm
 */
export const getStepLength = (height = 0, gender = 4) => {
	const H = gender === 1 ? 0.413 : gender === 2 ? 0.415 : 0.414;
	return (height ? height : gender === 2 ? 165 : 170) * H;
};

/**
 * 根据步数换算距离
 * @param {*} steps 步数
 * @param {*} stepLength 步长
 * @returns km = cm / 100 / 1000
 */
export const conversionDistanceBySteps = (steps, stepLength) => {
	return steps * stepLength / (100 * 1000);
};

/**
 * 根据步数换算卡路里
 * @param {*} distance 距离
 * @param {*} stepLength 步长
 * @returns kcal
 */
export const conversionCalorieBySteps = (weight = 0, distance, gender = 2) => {
	return (weight ? weight : gender === 2 ? 53 : 65) * distance * 1.036;
};
